package com.sdk.es.http.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch._types.query_dsl.TermsQueryField;
import co.elastic.clients.json.JsonData;

import java.time.LocalDateTime;
import java.util.List;

public class MyQueryBuilders {

    public static <T> Query termQuery(String fieldName, T value) {
        Assert.notBlank(fieldName);
        Assert.notNull(value);
        return QueryBuilders.term()
                .field(fieldName)
                .value(TermsQueryFieldUtil.of(value))
                .build()
                ._toQuery();
    }

    public static <T> Query termsQuery(String fieldName, List<T> values) {
        Assert.notBlank(fieldName);
        Assert.notEmpty(values);
        TermsQueryField termsQueryField = TermsQueryFieldUtil.of(values);
        return QueryBuilders.terms()
                .field(fieldName)
                .terms(termsQueryField)
                .build()
                ._toQuery();
    }

    public static Query toBoolQuery(List<Query> queries) {
        return QueryBuilders.bool()
                .filter(queries)
                .build()
                ._toQuery();
    }

    public static Query rangQuery(String filedName, LocalDateTime from, LocalDateTime to) {
        return QueryBuilders.range()
                .field(filedName)
                .from(LocalDateTimeUtil.format(from, DatePattern.UTC_SIMPLE_MS_PATTERN))
                .to(LocalDateTimeUtil.format(to, DatePattern.UTC_SIMPLE_MS_PATTERN))
                .build()
                ._toQuery();
    }

    /**
     * 范围查询
     * @param filedName
     * @param from
     * @param to
     * @param equal 是否包含等于
     * @return
     */
    public static Query rangQuery(String filedName, long from, long to, boolean equal) {
        if (equal) {
            return QueryBuilders.range()
                    .field(filedName)
                    .gte(JsonData.of(from))
                    .lte(JsonData.of(to))
                    .build()
                    ._toQuery();
        } else {
            return QueryBuilders.range()
                    .field(filedName)
                    .gt(JsonData.of(from))
                    .lt(JsonData.of(to))
                    .build()
                    ._toQuery();
        }
    }

    public static Query ltQuery(String filedName, long to) {
        return QueryBuilders.range()
                .field(filedName)
                .lt(JsonData.of(to))
                .build()
                ._toQuery();
    }

    public static Query gtQuery(String filedName, long from) {
        return QueryBuilders.range()
                .field(filedName)
                .gt(JsonData.of(from))
                .build()
                ._toQuery();
    }

    public static Query idQuery(String id) {
        return QueryBuilders.ids().values(id).build()._toQuery();
    }

    public static Query existsQuery(String fieldName) {
        Assert.notBlank(fieldName);
        return QueryBuilders.exists()
                .field(fieldName)
                .build()
                ._toQuery();
    }

    /**
     * 模糊查询
     * @param fieldName
     * @param value
     * @return
     * @param <T>
     */
    public static <T> Query wildcardQuery(String fieldName, String value) {
        Assert.notBlank(fieldName);
        Assert.notNull(value);
        return QueryBuilders.wildcard()
                .field(fieldName)
                .value(value)
                .build()
                ._toQuery();
    }

    /**
     * 不等于查询
     * @param fieldName
     * @param value
     * @return
     * @param <T>
     */
    public static <T> Query mustNotQuery(String fieldName, String value) {
        Assert.notBlank(fieldName);
        Assert.notNull(value);
        return QueryBuilders.bool().mustNot(QueryBuilders.term().field(fieldName).value(TermsQueryFieldUtil.of(value)).build()._toQuery()).build()._toQuery();
    }
}
